fix(runtime): deliver the history-compact instruction as a trailing user message - #4797
Conversation
…ser message The history summarizer sent SUMMARIZATION_SYSTEM_PROMPT as provider instructions (system role). Agentic coding models such as kimi k3-256k ignore a system prompt in this shape and keep answering the conversation instead, so mid-turn compaction failed open forever with malformed_summary_missing_section (51 consecutive failed-open decisions observed; 180 history_compact calls and zero checkpoints on one workspace). A distinct system prompt also started the summarizer request outside the main loop's cached prefix, so every discarded attempt paid a full uncached pass (up to 88s observed). Fold the instruction into the trailing user message the request already ends with (apache#4559): generateSummary now appends one user message combining the sectioned prompt (or its shorten/repair variant) with the summary request, and AiSdkGenerateTextOptions drops the instructions field. Fixes apache#4634 Generated-by: GLM-5.3-Flash (ZCode)
hqhq1025
left a comment
There was a problem hiding this comment.
Reviewed exact head 903aac5ae22ac823724b3cc47ba83a90b342e54f.
No P0-P3 findings.
The change consistently removes the separate system-role instructions field and appends the full sectioned summarization prompt plus the existing summary request as the final user message for the initial call, output-limit retry, and malformed-summary repair. Rolling checkpoints still prepend the previous summary and replay only newly folded events. I also exercised the real AI SDK lowering with a mock language model: the provider-facing prompt retained the original conversation followed by one final user instruction and contained no system message.
Validation completed: Core, Storage, and Runtime builds; 139 focused compaction tests; full Runtime suite (3,201 passed, 13 skipped, 0 failed); repository lint, format, and ASF header checks; git diff --check; clean exact-main merge; and the hosted test check on this exact head.
Residual limitation: I did not call the live k3-256k endpoint, so provider-specific behavior is supported by the issue reproduction rather than independently re-run here.
Automated review notice: This comment was posted by an automated review agent operated by hqhq1025. It is not an independent human review and does not replace one.
Astro-Han
left a comment
There was a problem hiding this comment.
Thanks for the change. Approving exact head 903aac5ae22ac823724b3cc47ba83a90b342e54f following the completed review and Astro-Han’s explicit acceptance of this merge batch. Current checks pass and no review threads remain unresolved.
Some coding models ignored system-role compaction instructions and failed to produce a valid summary. Move the shared initial, shorten and repair instruction into the existing trailing user message, retaining output validation, budgets and checkpoint ownership. No persisted-data migration; cache benefit is not independently established.
AI assistance: Codex performed the review and final-state verification; Astro-Han authorized approval and merge.
中文
感谢改动。基于已完成的审查和 Astro-Han 对本批次的明确认可,批准当前精确 head;检查通过,讨论已结清。此前说明的验证边界与后续事项保持不变。本次由 Codex 执行审查和状态核对,Astro-Han 授权批准与合并。
Summary
Fixes the root cause of #4634: the history summarizer delivered
SUMMARIZATION_SYSTEM_PROMPTas provider instructions (system role). Agentic coding models such askimi-coding-plan/k3-256kignore that shape and keep answering the conversation, so every fold failed open withmalformed_summary_missing_section, and the distinct system prompt also forfeited the main loop's prefix cache for every discarded summarizer call.The instruction now rides as the request's trailing user message — the request already ended with one for chat-template models (#4559);
generateSummaryappends a single user message combining the sectioned prompt (or its shorten/repair variant) with the existing summary request, andAiSdkGenerateTextOptionsdrops the now-unusedinstructionsfield.Scope: direction 1 from the issue. Of the contributing defects listed there, the missing output cap is already fixed on current
mainby #4653 (DEFAULT_HISTORY_COMPACT_MAX_OUTPUT_TOKENS, landed 09-03, after the reporter's build); extending the failure circuit toprovider_error/output_lengthand bounding the summarizer input budget remain open follow-ups best split into their own issues.Verification
npm --workspace @maka/core run build && npm --workspace @maka/storage run build && npm --workspace @maka/runtime run build, thennode --testonhistory-compact-summarizer/effective-history-compaction/mid-turn-capacity-backenddist testsgit stash push -- packages/runtime/src/history-compact-summarizer.ts, rebuild, rerun the summarizer suitedelivers the summarization instruction as the trailing user message (#4634)instructionsfield reachesgenerateTextand the final user message carries both the sectioned prompt and the summary requestnpm run format:checknpm run check:asf-headersAI use
Implemented with ZCode (GLM-5.3-Flash): read the issue's reproduction data, traced the summarizer request shape in
packages/runtime/src/history-compact-summarizer.ts, and made the minimal request-shape change with a red-green regression test. The commit carries theGenerated-bytrailer.Checklist
node:test+assert/strict, issue number in the test name)